package de.ret_world.eet.code;

import java.util.ArrayList;

/**
 * Helper Class to convert data from and to UTF-8, Hex data and Binary data
 * @author Emu
 */
public class Convert {

    public enum DataType {

        UTF, Hex, Binary
    };

    /**
     * Converts data in strings
     * @param from from which data to convert
     * @param to to which data to convert
     * @param text the data string
     * @return the converted string
     */
    public static String convert(DataType from, DataType to, String text) {
        byte[] bytes = null;
        ArrayList<Byte> byt = null;

        switch (from) {
            case UTF:
                bytes = text.getBytes();
                break;
            case Hex:
                byt = new ArrayList<Byte>();
                if (text.length() % 2 != 0) {
                    throw new IllegalArgumentException("No hex string!");
                }
                for (int i = 0; i < text.length(); i += 2) {
                    String b = "#" + text.substring(i, i + 2);
                    byt.add(Integer.decode(b).byteValue());
                }

                bytes = new byte[byt.size()];
                for (int i = 0; i < byt.size(); i++) {
                    bytes[i] = byt.get(i);
                }
                break;
            case Binary:
                byt = new ArrayList<Byte>();
                if (text.length() % 8 != 0) {
                    throw new IllegalArgumentException("No binary string!");
                }
                for (int i = 0; i < text.length(); i += 8) {
                    String b = text.substring(i, i + 8);
                    byt.add(Integer.valueOf(b, 2).byteValue());
                }

                bytes = new byte[byt.size()];
                for (int i = 0; i < byt.size(); i++) {
                    bytes[i] = byt.get(i);
                }
                break;
        }

        String result = null;
        StringBuilder bin = null;

        switch (to) {
            case UTF:
                result = new String(bytes);
                break;
            case Hex:
                bin = new StringBuilder();

                for (byte b : bytes) {
                    String tmp = Integer.toHexString(b).toUpperCase();
                    if (tmp.length() < 2) {
                        tmp = "0" + tmp;
                    } else if (tmp.length() > 2) {
                        tmp = tmp.substring(tmp.length() - 2, tmp.length());
                    }

                    bin.append(tmp);
                }
                result = bin.toString();
                break;
            case Binary:
                bin = new StringBuilder();

                for (byte b : bytes) {
                    String tmp = Integer.toBinaryString(b);
                    int diff = 8 - tmp.length();
                    if (diff > 0) {
                        for (int x = 0; x < diff; x++) {
                            if (b > 0) {
                                tmp = "0" + tmp;
                            } else {
                                tmp = "1" + tmp;
                            }
                        }
                    } else {
                        tmp = tmp.substring(tmp.length() - 8, tmp.length());
                    }
                    bin.append(tmp);
                }
                result = bin.toString();
                break;
        }


        return result;
    }
}
